<template>
  <div class="chat-container">
    <!-- 侧边栏 -->
    <div :class="['sidebar', { collapsed: isSidebarCollapsed }]">
      <div class="sidebar-header">
        <h2 v-if="!isSidebarCollapsed">edu-Agent</h2>
        <a-button type="text" @click="toggleSidebar" class="toggle-btn">
          <i :class="isSidebarCollapsed ? 'fa fa-bars' : 'fa fa-times'"></i>
        </a-button>
      </div>

      <div class="sidebar-content">
        <a-button type="primary" block @click="toCreateNewSession" class="new-session-btn">
          <template #icon>
            <PlusOutlined />
          </template>
          <span v-if="!isSidebarCollapsed">新建会话 (Ctrl+K)</span>
        </a-button>

        <div class="mode-selector">
          <a-menu v-model:selectedKeys="selectedMode" mode="vertical" @click="handleModeChange">
            <a-menu-item key="chat">
              <template #icon v-if="!isSidebarCollapsed">
                <MessageOutlined />
              </template>
              <span v-if="!isSidebarCollapsed">RAG对话</span>
            </a-menu-item>
            <a-menu-item key="document">
              <template #icon v-if="!isSidebarCollapsed">
                <FileTextOutlined />
              </template>
              <span v-if="!isSidebarCollapsed">文档总结</span>
            </a-menu-item>
          </a-menu>
        </div>

        <div class="history-section" v-if="!isSidebarCollapsed">
          <h3><i class="fa fa-history"></i> 历史会话</h3>
          <div
            v-for="session in recentSessions"
            :key="session.id"
            class="session-item"
            :class="{ active: currentSession?.id === session.id }"
            @click="selectSession(session)"
          >
            <div class="session-info">
              <span class="session-title">{{ session.title.substring(0, 9) }}</span>
              <span class="session-time"
                ><i class="fa fa-clock-o"></i> {{ formatTime(session.createTime) }}</span
              >
            </div>
            <a-dropdown>
              <a class="ant-dropdown-link" @click.prevent>
                <EllipsisOutlined />
              </a>
              <template #overlay>
                <a-menu>
                  <a-menu-item @click="editSessionTitle(session)">
                    <EditOutlined /> 编辑标题
                  </a-menu-item>
                  <a-menu-item @click="pinSession(session)"> <PushpinOutlined /> 置顶 </a-menu-item>
                  <a-menu-item @click="deleteSession(session)">
                    <DeleteOutlined /> 删除
                  </a-menu-item>
                </a-menu>
              </template>
            </a-dropdown>
          </div>
          <a-button type="link" @click="viewAllSessions" block class="view-all-btn">
            <i class="fa fa-list"></i> 查看全部
          </a-button>
        </div>
      </div>

      <div class="sidebar-footer" v-if="!isSidebarCollapsed">
        <a-button @click="toggleFullscreen" block>
          <template #icon>
            <FullscreenExitOutlined v-if="isFullscreen" />
            <FullscreenOutlined v-else />
          </template>
          {{ isFullscreen ? '退出全屏' : '全屏模式' }}
        </a-button>
      </div>
    </div>

    <!-- 主内容区 -->
    <div class="main-content">
      <!-- 初始状态 -->
      <div v-if="!currentSession && chatMode === 'chat'" class="initial-state">
        <div class="welcome-section">
          <h1>edu-Agent</h1>
          <div class="input-container-wrapper">
            <div class="input-container">
              <a-textarea
                v-model:value="userInput"
                placeholder="请输入您的问题...(Enter=发送，Shfit + Enter=换行)"
                :auto-size="{ minRows: 3, maxRows: 6 }"
                @keydown.enter.prevent="handleTextareaKeyDown"
                class="main-input"
              />
              <div class="input-actions">
                <a-tooltip placement="bottom">
                  <template #title>提高结果质量</template>
                  <a-button
                    type="text"
                    class="action-btn deep-thinking-btn"
                    @click="toggleDeepThinking"
                    :class="{ active: isDeepThinking }"
                  >
                    <BulbOutlined /> 深度思考
                  </a-button>
                </a-tooltip>
                <a-tooltip placement="bottom">
                  <template #title>开启后会通过互联网检索资料</template>
                  <a-button
                    type="text"
                    class="action-btn web-search-btn"
                    @click="toggleWebSearch"
                    :class="{ active: isWebSearch }"
                  >
                    <GlobalOutlined /> 联网搜索
                  </a-button>
                </a-tooltip>
                <a-tooltip placement="bottom">
                  <template #title
                    >支持上传文件（最多50个，每个100MB）接受pdf、doc、xlsx、ppt、txt、图片等</template
                  >
                  <a-button
                    type="text"
                    class="action-btn attachment-btn"
                    @click="showAttachmentInfo"
                  >
                    <PaperClipOutlined />
                  </a-button>
                </a-tooltip>
                <a-tooltip placement="bottom">
                  <template #title>提高用户询问质量，增强回答模型效果</template>
                  <a-button
                    type="text"
                    class="action-btn enhance-btn"
                    :class="{ animating: showEnhanceAnimation }"
                    @click="enhancePrompt"
                    :loading="isEnhancingPrompt"
                    :disabled="!userInput.trim() || isEnhancingPrompt"
                  >
                    <HighlightOutlined />
                    <!--                  提示词增强-->
                  </a-button>
                </a-tooltip>
                <a-button
                  type="primary"
                  @click="handleSend"
                  :disabled="!userInput.trim() || isSending"
                  class="send-btn"
                >
                  <span v-if="!isSending">发送</span>
                  <span v-else>中断</span>
                </a-button>
              </div>
            </div>
          </div>
          <div class="quick-questions">
            <h3><i class="fa fa-bolt"></i> 快速提问</h3>
            <div class="question-row">
              <a-button
                v-for="(question, index) in currentQuickQuestions.firstRow"
                :key="'first-' + index"
                type="default"
                @click="selectQuickQuestion(question.text)"
              >
                <i :class="question.icon" :style="{ color: question.color }"></i>
                {{ question.text }}
              </a-button>
            </div>
            <div class="question-row">
              <a-button
                v-for="(question, index) in currentQuickQuestions.secondRow"
                :key="'second-' + index"
                type="default"
                @click="selectQuickQuestion(question.text)"
              >
                <i :class="question.icon" :style="{ color: question.color }"></i>
                {{ question.text }}
              </a-button>
            </div>
          </div>
        </div>
      </div>

      <!-- 对话状态 -->
      <div v-else-if="chatMode === 'chat'" class="chat-state">
        <div class="chat-header">
          <a-button @click="showModelSelector = true">
            <template #icon>
              <RobotOutlined />
            </template>
            {{ selectedModel?.modelName || '选择模型' }}
          </a-button>
          <a-button
            v-if="chatType === 'default'"
            @click="openThePromptModal"
            style="margin-left: 10px"
          >
            <template #icon>
              <FileSearchOutlined />
            </template>
            选择提示词
          </a-button>
        </div>

        <div class="messages-container" ref="messagesContainer">
          <!-- 加载更多按钮 -->
          <div v-if="hasMoreHistory" class="load-more-container">
            <a-button
              type="link"
              @click="loadMoreHistory(currentSession?.id)"
              :loading="loadingHistory"
              size="small"
            >
              加载更多历史消息
            </a-button>
          </div>
          <div class="messages-wrapper">
            <div v-for="message in messages" :key="message.id" :class="['message', message.role]">
              <div class="message-avatar">
                <img
                  v-if="message.role === 'user' && loginUserStore.loginUser.userAvatar"
                  :src="loginUserStore.loginUser.userAvatar"
                  :alt="loginUserStore.loginUser.userName || '用户头像'"
                />
                <img
                  v-else-if="message.role === 'assistant'"
                  src="@/assets/logo.png"
                  alt="AI助手头像"
                />
                <UserOutlined
                  v-else-if="message.role === 'user' && !loginUserStore.loginUser.userAvatar"
                />
                <RobotOutlined v-else />
              </div>
              <div class="message-content">
                <div class="message-header" v-if="message.role === 'assistant'">
                  <span class="assistant-label"><i class="fa fa-robot"></i> AI助手</span>
                </div>
                <div
                  v-if="message.loading && isDeepThinking && !message.thinkingContent"
                  class="loading-indicator"
                >
                  <a-spin size="small" />
                  <span class="loading-text">AI正在思考中...</span>
                </div>
                <div
                  class="deep-thinking-section"
                  v-else-if="message.role === 'assistant' && message.thinkingContent"
                >
                  <a-collapse :default-active-key="['1']">
                    <a-collapse-panel key="1" header="🤔深度思考过程">
                      <div
                        class="thinking-content"
                        v-html="renderMarkdown(message.thinkingContent)"
                      ></div>
                    </a-collapse-panel>
                  </a-collapse>
                </div>
                <div class="message-text" v-html="renderMarkdown(message.content)"></div>
                <div class="message-actions">
                  <a-button type="text" size="small" @click="copyMessage(message)">
                    <CopyOutlined /> 复制
                  </a-button>
                  <a-button
                    v-if="message.role === 'assistant'"
                    type="text"
                    size="small"
                    @click="retryMessage(message)"
                  >
                    <RedoOutlined /> 重试
                  </a-button>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="toBottom" :class="{ sending: isSending }">
          <a-button @click="scrollToBottom" class="scroll-button">
            <ArrowDownOutlined />
          </a-button>
          <div class="arc-animation" v-if="isSending"></div>
        </div>
        <div class="input-container-wrapper">
          <div class="input-container">
            <a-textarea
              v-model:value="userInput"
              placeholder="请输入您的问题...(Enter=发送，Shfit + Enter=换行)"
              :auto-size="{ minRows: 3, maxRows: 6 }"
              @pressEnter="handleSend"
              class="main-input"
            />
            <div class="input-actions">
              <a-tooltip placement="top">
                <template #title>提高结果质量</template>
                <a-button
                  type="text"
                  class="action-btn deep-thinking-btn"
                  @click="toggleDeepThinking"
                  :class="{ active: isDeepThinking }"
                >
                  <BulbOutlined /> 深度思考
                </a-button>
              </a-tooltip>
              <a-tooltip placement="top">
                <template #title>开启后会通过互联网检索资料</template>
                <a-button
                  type="text"
                  class="action-btn web-search-btn"
                  @click="toggleWebSearch"
                  :class="{ active: isWebSearch }"
                >
                  <GlobalOutlined /> 联网搜索
                </a-button>
              </a-tooltip>
              <a-tooltip placement="top">
                <template #title
                  >支持上传文件（最多50个，每个100MB）接受pdf、doc、xlsx、ppt、txt、图片等</template
                >
                <a-button type="text" class="action-btn attachment-btn" @click="showAttachmentInfo">
                  <PaperClipOutlined />
                </a-button>
              </a-tooltip>
              <a-tooltip placement="top">
                <template #title>提高用户询问质量，增强回答模型效果</template>
                <a-button
                  type="text"
                  class="action-btn enhance-btn"
                  :class="{ animating: showEnhanceAnimation }"
                  @click="enhancePrompt"
                  :loading="isEnhancingPrompt"
                  :disabled="!userInput.trim() || isEnhancingPrompt"
                >
                  <HighlightOutlined />
                  <!--                  提示词增强-->
                </a-button>
              </a-tooltip>
              <a-button
                type="primary"
                @click="handleSend"
                :disabled="!userInput.trim() || isSending"
                class="send-btn"
              >
                <span v-if="!isSending">发送</span>
                <span v-else>中断</span>
              </a-button>
            </div>
          </div>
        </div>
      </div>

      <!-- 文档总结状态 -->
      <div v-else-if="chatMode === 'document'" class="document-state">
        <div class="document-container">
          <h2><i class="fa fa-file-text"></i> 文档总结</h2>
          <p>上传文件或输入文件链接进行文档总结</p>

          <div class="upload-section">
            <a-upload-dragger
              name="file"
              :multiple="true"
              :max-count="50"
              :before-upload="beforeUpload"
            >
              <p class="ant-upload-drag-icon">
                <InboxOutlined />
              </p>
              <p class="ant-upload-text">
                <i class="fa fa-cloud-upload"></i> 点击或拖拽文件到此区域上传
              </p>
              <p class="ant-upload-hint">支持单次上传最多50个文件，每个文件不超过100MB</p>
            </a-upload-dragger>

            <div class="link-input">
              <a-input
                v-model:value="documentLink"
                placeholder="或输入文件链接"
                addon-before="链接"
              />
              <a-button
                type="primary"
                @click="processDocumentLink"
                :disabled="!documentLink"
                style="margin-top: 10px"
              >
                <i class="fa fa-link"></i> 处理链接
              </a-button>
            </div>
          </div>

          <!-- 文档总结结果模态框 -->
          <a-modal
            v-model:open="showDocumentSummary"
            title="文档总结结果"
            width="800px"
            :footer="null"
          >
            <div class="summary-content" v-html="renderMarkdown(documentSummary)"></div>
          </a-modal>
        </div>
      </div>

      <!-- 历史会话状态 -->
      <div v-else-if="chatMode === 'history'" class="history-state" @scroll="handleHistoryScroll">
        <div class="history-header">
          <h2><i class="fa fa-history"></i> 历史会话</h2>
          <a-input-search
            v-model:value="searchKeyword"
            placeholder="搜索历史会话"
            style="height: 10px; margin-bottom: 20px"
            @search="searchSessions"
          />
        </div>

        <div class="history-list">
          <!-- 今天 -->
          <div v-if="categorizedSessions.today.length > 0" class="time-section">
            <h3 class="time-title">今天</h3>
            <div
              v-for="session in categorizedSessions.today"
              :key="session.id"
              class="history-item"
              @click="selectSession(session)"
            >
              <div class="history-info">
                <h3><i class="fa fa-comment"></i> {{ session.title }}</h3>
                <p>{{ session.preview }}</p>
                <span class="history-time"
                  ><i class="fa fa-clock-o"></i> {{ formatTime(session.createTime) }}</span
                >
              </div>
            </div>
          </div>

          <!-- 本周 -->
          <div v-if="categorizedSessions.thisWeek.length > 0" class="time-section">
            <h3 class="time-title">本周</h3>
            <div
              v-for="session in categorizedSessions.thisWeek"
              :key="session.id"
              class="history-item"
              @click="selectSession(session)"
            >
              <div class="history-info">
                <h3><i class="fa fa-comment"></i> {{ session.title }}</h3>
                <p>{{ session.preview }}</p>
                <span class="history-time"
                  ><i class="fa fa-clock-o"></i> {{ formatTime(session.createTime) }}</span
                >
              </div>
            </div>
          </div>

          <!-- 本月 -->
          <div v-if="categorizedSessions.thisMonth.length > 0" class="time-section">
            <h3 class="time-title">本月</h3>
            <div
              v-for="session in categorizedSessions.thisMonth"
              :key="session.id"
              class="history-item"
              @click="selectSession(session)"
            >
              <div class="history-info">
                <h3><i class="fa fa-comment"></i> {{ session.title }}</h3>
                <p>{{ session.preview }}</p>
                <span class="history-time"
                  ><i class="fa fa-clock-o"></i> {{ formatTime(session.createTime) }}</span
                >
              </div>
            </div>
          </div>

          <!-- 本年 -->
          <div v-if="categorizedSessions.thisYear.length > 0" class="time-section">
            <h3 class="time-title">本年</h3>
            <div
              v-for="session in categorizedSessions.thisYear"
              :key="session.id"
              class="history-item"
              @click="selectSession(session)"
            >
              <div class="history-info">
                <h3><i class="fa fa-comment"></i> {{ session.title }}</h3>
                <p>{{ session.preview }}</p>
                <span class="history-time"
                  ><i class="fa fa-clock-o"></i> {{ formatTime(session.createTime) }}</span
                >
              </div>
            </div>
          </div>
        </div>

        <!-- 滚动加载更多 -->
        <div v-if="hasMoreSessions" class="load-more-trigger" @mouseenter="loadMoreSessions">
          <a-spin v-if="loadingSessions" />
          <div v-else class="load-more-text">
            <!-- <i class="fa fa-arrow-down"></i> -->
          </div>
        </div>
      </div>
    </div>

    <!-- 右侧抽屉 - 联网搜索内容 -->
    <a-drawer
      title="联网搜索结果"
      placement="right"
      :visible="showSearchDrawer"
      @close="showSearchDrawer = false"
      width="400"
    >
      <div class="search-results">
        <h3><i class="fa fa-search"></i> 搜索结果</h3>
        <div v-for="(result, index) in searchResults" :key="index" class="search-result-item">
          <h4><i class="fa fa-link"></i> {{ result.title }}</h4>
          <p>{{ result.content }}</p>
          <a :href="result.url" target="_blank">{{ result.url }}</a>
        </div>
      </div>
    </a-drawer>

    <!-- 模型选择模态框 -->
    <a-modal
      v-model:open="showModelSelector"
      title="选择模型"
      @ok="confirmModelSelection"
      @cancel="showModelSelector = false"
      width="800px"
    >
      <h3><i class="fa fa-robot"></i> 可用模型</h3>
      <div class="model-cards-container">
        <div
          v-for="model in availableModels"
          :key="model.modelName"
          class="model-card"
          :class="{ selected: selectedModel?.modelName === model.modelName }"
          @click="selectModel(model)"
        >
          <div class="model-avatar">
            <img :src="getModelAvatar(model.modelName)" :alt="model.modelName" />
          </div>
          <div class="model-info">
            <div class="model-name">{{ model.modelName }}</div>
            <div class="model-description">{{ model.description }}</div>
          </div>
        </div>
      </div>
    </a-modal>
    <!-- 提示词选择模态框 -->
    <a-modal v-model:open="showPromptModal" title="选择提示词" width="800px">
      <div class="prompt-categories">
        <!-- 科目选择区域 -->
        <div class="subject-tabs">
          <a-tabs v-model:activeKey="selectedSubject" @change="handleSubjectChange">
            <a-tab-pane key="" tab="全部"></a-tab-pane>
            <a-tab-pane
              v-for="subject in promptTypeList"
              :key="subject"
              :tab="subject"
            ></a-tab-pane>
          </a-tabs>
        </div>

        <!-- 提示词卡片展示区域 -->
        <div class="prompt-cards-container">
          <div
            v-for="prompt in filteredPromptList"
            :key="prompt.id"
            class="prompt-card"
            :class="{ active: selectedPrompt?.id === prompt.id }"
            @click="selectPrompt(prompt)"
          >
            <div class="card-header">
              <a-avatar class="card-avatar">{{ prompt.subject?.charAt(0) }}</a-avatar>
              <div class="card-title">{{ prompt.role }}</div>
            </div>
            <div class="card-desc">{{ prompt.effect }}</div>
          </div>
        </div>
      </div>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, nextTick, computed, onUnmounted, reactive } from 'vue'
import {
  PlusOutlined,
  MessageOutlined,
  FileTextOutlined,
  EllipsisOutlined,
  EditOutlined,
  PushpinOutlined,
  DeleteOutlined,
  FullscreenOutlined,
  FullscreenExitOutlined,
  BulbOutlined,
  GlobalOutlined,
  HighlightOutlined,
  PaperClipOutlined,
  RobotOutlined,
  FileSearchOutlined,
  UserOutlined,
  CopyOutlined,
  RedoOutlined,
  InboxOutlined,
  ArrowDownOutlined,
} from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import MarkdownIt from 'markdown-it'
import hljs from 'highlight.js'
import api from '@/api'
import { API_BASE_URL } from '@/config/env'
import { useLoginUserStore } from '@/store/user'
import { useCommonStore } from '@/store/common'
import { listPromptSelfVoByPage } from '@/api/promptSelfController'
import { enhanceTheUserPrompt } from '@/api/learnChatController'
import {
  getNoReasoningContent,
  getReasoningContent,
  ThinkStreamParser,
} from '@/utils/ReasoningContentParser'
const commonStore = useCommonStore()
// 类型定义
interface ChatSession {
  id: number
  title: string
  createTime: string
  preview?: string
}

interface Message {
  id: number
  role: 'user' | 'assistant'
  content: string
  thinkingContent?: string // 添加思考内容字段
  createTime?: string
  loading?: boolean // 添加loading状态
}

interface ModelView {
  modelName?: string
  description?: string
}

// 响应式数据
const isSidebarCollapsed = ref(false)
const isFullscreen = ref(commonStore.getFullscreen())
const chatMode = ref<'chat' | 'document' | 'history'>('chat')
const chatType = ref<'default' | 'rag'>('default')
const selectedMode = ref<string[]>(['chat'])
const currentSession = ref<ChatSession | null>(null)
const userInput = ref('')
const documentLink = ref('')
const isSending = ref(false)
const messages = ref<Message[]>([])
const recentSessions = ref<ChatSession[]>([])
const allSessions = ref<ChatSession[]>([])
const searchKeyword = ref('')
const showSearchDrawer = ref(false)
const searchResults = ref<any[]>([])

// 功能开关
const isDeepThinking = ref(false)
const isWebSearch = ref(false)

// 深度思考内容
const deepThinkingContent = ref('')

// 增强提示词相关状态
const isEnhancingPrompt = ref(false)
const originalPrompt = ref('')
const enhancedPrompt = ref('')
const showEnhanceAnimation = ref(false)
const animationProgress = ref(0)

// 思考消息解析器实例
let thinkParser: ThinkStreamParser | null = null

// 文档总结相关
const showDocumentSummary = ref(false)
const documentSummary = ref('')

// 模型和提示词相关
const showModelSelector = ref(false)
const availableModels = ref<ModelView[]>([])
const selectedModel = ref<ModelView | null>(null)
const selectedPrompt = ref<API.PromptSelfVO | null>(null)

// Markdown渲染器
const md = MarkdownIt({
  highlight: function (str, lang) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return hljs.highlight(str, { language: lang }).value
      } catch (__) {}
    }
    return '' // 使用默认处理
  },
})

// EventSource引用
let eventSource: any = null

// 计算属性
const messagesContainer = ref<HTMLElement | null>(null)

// 用户存储
const loginUserStore = useLoginUserStore()

// 方法实现
const toggleSidebar = () => {
  isSidebarCollapsed.value = !isSidebarCollapsed.value
}

const toggleFullscreen = () => {
  isFullscreen.value = !isFullscreen.value
  commonStore.setFullscreen(isFullscreen.value)
}

const toggleDeepThinking = () => {
  isDeepThinking.value = !isDeepThinking.value
}

const toggleWebSearch = () => {
  isWebSearch.value = !isWebSearch.value
}

const enhancePrompt = async () => {
  if (!userInput.value.trim()) {
    message.warning('请先输入提示词内容')
    return
  }

  if (isEnhancingPrompt.value) {
    message.warning('正在增强提示词，请稍候')
    return
  }

  try {
    isEnhancingPrompt.value = true
    originalPrompt.value = userInput.value

    // 调用增强提示词API
    const response = await enhanceTheUserPrompt({
      originalPrompt: userInput.value,
    })

    if (response.data?.code === 0 && response.data.data) {
      enhancedPrompt.value = response.data.data

      // 显示动画效果
      showEnhanceAnimation.value = true
      animationProgress.value = 0

      // 给输入框添加光芒效果类
      const inputElement = document.querySelector('.main-input') as HTMLElement
      if (inputElement) {
        inputElement.classList.add('input-with-shine')
      }

      // 动画效果：原始提示词 -> 帷幕拉开闪耀特效 -> 增强后的提示词
      const animatePrompt = () => {
        // 第一阶段：显示原始提示词
        setTimeout(() => {
          // 第二阶段：帷幕拉开闪耀特效
          const shineDuration = 2000 // 闪耀总时长
          const frameRate = 60 // 帧率
          const totalFrames = shineDuration / (1000 / frameRate)

          let currentFrame = 0
          const curtainShineEffect = () => {
            if (currentFrame <= totalFrames) {
              const progress = currentFrame / totalFrames

              // 创建帷幕拉开闪耀效果
              let displayText = ''

              // 根据进度决定显示的内容
              if (progress < 0.2) {
                // 前期：原始提示词逐渐变暗
                const darkness = 1 - (progress / 0.2) * 0.7
                displayText = originalPrompt.value
                // 这里我们通过CSS控制透明度，而不是修改文本
              } else if (progress < 0.8) {
                // 中期：帷幕拉开，光芒闪耀
                const midProgress = (progress - 0.2) / 0.6
                const revealProgress = Math.min(midProgress * 1.5, 1)

                // 计算当前显示的文本长度
                const originalLength = originalPrompt.value.length
                const enhancedLength = enhancedPrompt.value.length
                const currentLength = Math.floor(
                  originalLength + (enhancedLength - originalLength) * revealProgress,
                )

                // 显示部分增强后的提示词
                displayText = enhancedPrompt.value.substring(0, currentLength)

                // 添加光晕效果（通过CSS类控制）
                if (midProgress < 0.3) {
                  // 光芒逐渐增强
                  showEnhanceAnimation.value = true
                } else if (midProgress > 0.7) {
                  // 光芒逐渐减弱
                  showEnhanceAnimation.value = false
                }
              } else {
                // 后期：完全显示增强后的提示词
                displayText = enhancedPrompt.value
                showEnhanceAnimation.value = false
              }

              userInput.value = displayText
              currentFrame++
              setTimeout(curtainShineEffect, 1000 / frameRate)
            } else {
              // 第三阶段：显示完整的增强后的提示词
              userInput.value = enhancedPrompt.value
              showEnhanceAnimation.value = false

              // 移除输入框的光芒效果类
              if (inputElement) {
                inputElement.classList.remove('input-with-shine')
              }

              isEnhancingPrompt.value = false
              message.success('提示词已增强')
            }
          }

          curtainShineEffect()
        }, 300)
      }

      animatePrompt()
    } else {
      message.error('增强提示词失败')
      isEnhancingPrompt.value = false

      // 确保移除输入框的光芒效果类
      const inputElement = document.querySelector('.main-input') as HTMLElement
      if (inputElement) {
        inputElement.classList.remove('input-with-shine')
      }
    }
  } catch (error) {
    console.error('增强提示词出错:', error)
    message.error('增强提示词出错')
    isEnhancingPrompt.value = false

    // 确保移除输入框的光芒效果类
    const inputElement = document.querySelector('.main-input') as HTMLElement
    if (inputElement) {
      inputElement.classList.remove('input-with-shine')
    }
  }
}
const toCreateNewSession = () => {
  //直接切换到 初始页面即可
  currentSession.value = null
  chatMode.value = 'chat'
}
const createNewSession = async () => {
  try {
    // 调用API创建新会话
    const response = await api.learnChatController.addLearnChat({
      initPrompt: userInput.value || '新会话',
    })

    if (response.data?.code === 0) {
      currentSession.value = {
        id: response.data.data!,
        title: userInput.value || '新会话',
        createTime: new Date().toISOString(),
      }
      messages.value = []
      chatMode.value = 'chat'
    }
  } catch (error) {
    console.error('创建会话失败:', error)
    message.error('创建会话失败')
  }
}

const handleModeChange = ({ key }: { key: string }) => {
  if (key === 'chat') {
    chatMode.value = 'chat'
    chatType.value = 'default'
  } else if (key === 'rag') {
    chatMode.value = 'chat'
    chatType.value = 'rag'
  } else if (key === 'document') {
    chatMode.value = 'document'
  }
}

const selectSession = async (session: ChatSession) => {
  currentSession.value = session
  chatMode.value = 'chat'
  // 加载会话消息
  await loadSessionMessages(session.id)
  // 滚动到最底部
  scrollToBottom()
}

const editSessionTitle = async (session: ChatSession) => {
  // 编辑会话标题逻辑
  const newTitle = prompt('请输入新标题:', session.title)
  if (newTitle) {
    try {
      await api.learnChatController.updateLearnChat({
        id: session.id,
        title: newTitle,
      })
      session.title = newTitle
      if (currentSession.value?.id === session.id) {
        currentSession.value.title = newTitle
      }
      message.success('标题更新成功')
    } catch (error) {
      console.error('更新会话标题失败:', error)
      message.error('更新会话标题失败')
    }
  }
}

const pinSession = (session: ChatSession) => {
  // 置顶会话逻辑
  message.success('会话已置顶')
}
/**
 *
 * @param session
 */
const deleteSession = async (session: ChatSession) => {
  // 删除会话逻辑
  try {
    const response = await api.learnChatController.deleteLearnChat({
      id: session.id,
    })

    if (response.data?.code === 0) {
      recentSessions.value = recentSessions.value.filter((s) => s.id !== session.id)
      if (currentSession.value?.id === session.id) {
        currentSession.value = null
        messages.value = []
      }
      message.success('会话已删除')
    }
  } catch (error) {
    console.error('删除会话失败:', error)
    message.error('删除会话失败')
  }
}

const viewAllSessions = async () => {
  chatMode.value = 'history'
  await loadAllSessions()
}

/**
 * 快速提问  todo
 * @param question
 */
// 快捷提问数据
const quickQuestionsSets = [
  {
    firstRow: [
      { text: '什么是人工智能？', icon: 'fa fa-robot', color: '#3498db' },
      { text: '机器学习和深度学习有什么区别？', icon: 'fa fa-brain', color: '#9b59b6' },
    ],
    secondRow: [
      { text: '如何提高编程能力？', icon: 'fa fa-code', color: '#2ecc71' },
      { text: '推荐一些学习Python的资源', icon: 'fa fa-book', color: '#e74c3c' },
      { text: '解释一下区块链技术', icon: 'fa fa-link', color: '#f39c12' },
    ],
  },
  {
    firstRow: [
      { text: '什么是量子计算？', icon: 'fa fa-atom', color: '#1abc9c' },
      { text: '5G技术有哪些应用场景？', icon: 'fa fa-wifi', color: '#34495e' },
    ],
    secondRow: [
      { text: '如何保护个人隐私数据？', icon: 'fa fa-shield-alt', color: '#e67e22' },
      { text: '云计算的优势是什么？', icon: 'fa fa-cloud', color: '#95a5a6' },
      { text: '什么是边缘计算？', icon: 'fa fa-microchip', color: '#16a085' },
    ],
  },
  {
    firstRow: [
      { text: '什么是元宇宙？', icon: 'fa fa-vr-cardboard', color: '#8e44ad' },
      { text: '自动驾驶技术如何工作？', icon: 'fa fa-car', color: '#c0392b' },
    ],
    secondRow: [
      { text: '如何进行数据可视化？', icon: 'fa fa-chart-bar', color: '#27ae60' },
      { text: '推荐一些AI绘画工具', icon: 'fa fa-palette', color: '#2980b9' },
      { text: '什么是物联网？', icon: 'fa fa-network-wired', color: '#d35400' },
    ],
  },
]

// 当前显示的快捷提问
const currentQuickQuestions = ref(quickQuestionsSets[0])
// 当前显示的快捷提问索引
const currentQuickQuestionIndex = ref(0)
// 定时器引用
let quickQuestionTimer: NodeJS.Timeout | null = null

// 切换快捷提问
const switchQuickQuestions = () => {
  currentQuickQuestionIndex.value =
    (currentQuickQuestionIndex.value + 1) % quickQuestionsSets.length
  currentQuickQuestions.value = quickQuestionsSets[currentQuickQuestionIndex.value]
}

// 启动快捷提问定时切换
const startQuickQuestionTimer = () => {
  // 清除现有定时器
  if (quickQuestionTimer) {
    clearInterval(quickQuestionTimer)
  }
  // 设置新定时器，每分钟切换一次
  quickQuestionTimer = setInterval(switchQuickQuestions, 60000)
}

// 停止快捷提问定时切换
const stopQuickQuestionTimer = () => {
  if (quickQuestionTimer) {
    clearInterval(quickQuestionTimer)
    quickQuestionTimer = null
  }
}

const selectQuickQuestion = (question: string) => {
  userInput.value = question
  handleSend()
}

// 处理文本域键盘事件，实现Shift + Enter换行功能
const handleTextareaKeyDown = (event: KeyboardEvent) => {
  // 如果按下的是Shift + Enter，则在文本域内换行
  if (event.shiftKey && event.key === 'Enter') {
    // 获取当前光标位置
    const textarea = event.target as HTMLTextAreaElement
    const startPos = textarea.selectionStart
    const endPos = textarea.selectionEnd

    // 在光标位置插入换行符
    const newValue =
      userInput.value.substring(0, startPos) + '\n' + userInput.value.substring(endPos)
    userInput.value = newValue

    // 恢复光标位置（在换行符后）
    setTimeout(() => {
      textarea.selectionStart = startPos + 1
      textarea.selectionEnd = startPos + 1
    }, 0)
  }
  // 如果只按下Enter，则发送消息
  else if (event.key === 'Enter') {
    handleSend()
  }
}

const handleSend = async () => {
  if (!userInput.value.trim() || isSending.value) return

  // 如果正在发送，点击按钮则中断
  if (isSending.value) {
    interruptSending()
    return
  }

  // 创建新会话（如果还没有）
  if (!currentSession.value) {
    await createNewSession()
  }

  // 添加用户消息
  const userMessage: Message = {
    id: Date.now(),
    role: 'user',
    content: userInput.value,
  }
  messages.value.push(userMessage)

  // 清空输入框
  userInput.value = ''

  // 滚动到底部
  scrollToBottom()

  // 发送消息并接收回复
  await sendUserMessage(userMessage)
}
/**
 * 发送用户消息
 * @param userMessage
 */
const sendUserMessage = async (userMessage: Message) => {
  isSending.value = true
  deepThinkingContent.value = ''
  // 如果开启了思考模式
  if (isDeepThinking.value) {
    // 初始化思考消息解析器
    thinkParser = new ThinkStreamParser((ch) => {
      deepThinkingContent.value += ch // 响应式累加
    })
  }

  // 创建AI助手消息
  const aiMessage: Message = {
    id: Date.now() + 1,
    role: 'assistant',
    content: '',
    thinkingContent: '', // 初始化思考内容
    loading: true,
  }
  messages.value.push(aiMessage)

  try {
    // 根据聊天类型选择不同的API
    // const params = new URLSearchParams({
    //   learnChatId: currentSession.value!.id || '',
    //   message: encodeURIComponent(userMessage.content),
    // })
    let eventSourceUrl = ''
    if (chatType.value === 'rag') {
      // RAG对话
      if (isDeepThinking.value) {
        eventSourceUrl = `${API_BASE_URL}/rag/deep-thinking/chat?learnChatId=${currentSession.value!.id}&message=${encodeURIComponent(userMessage.content)}`
      } else {
        eventSourceUrl = `${API_BASE_URL}/rag/chat?learnChatId=${currentSession.value!.id}&message=${encodeURIComponent(userMessage.content)}`
      }
    } else {
      // 普通对话
      if (isDeepThinking.value) {
        eventSourceUrl = `${API_BASE_URL}/chat/deep-thinking/chat/model/learn?learnChatId=${currentSession.value!.id}&message=${encodeURIComponent(userMessage.content)}`
      } else {
        eventSourceUrl = `${API_BASE_URL}/chat/chat/model/learn?learnChatId=${currentSession.value!.id}&message=${encodeURIComponent(userMessage.content)}`
      }
    }
    //如果选择了模型，添加模型参数
    if (selectedModel.value != null) {
      eventSourceUrl += `&model=${selectedModel.value.modelName}`
    }
    //如果选择了提示词，添加提示词参数
    if (selectedPrompt.value != null) {
      eventSourceUrl += `&promptId=${selectedPrompt.value.id}`
    }
    // 创建EventSource连接
    eventSource = new EventSource(eventSourceUrl, {
      withCredentials: true, // 凭证
    })

    // 处理SSE响应
    handleSseResponse(eventSource)
  } catch (error) {
    console.error('发送消息失败:', error)
    message.error('发送消息失败')
    isSending.value = false
  }
}
/**
 * 处理sse响应
 * @param eventSource
 */
const handleSseResponse = (eventSource: EventSource) => {
  let streamCompleted = false
  let fullContent = ''
  eventSource.onmessage = (event) => {
    if (streamCompleted) return
    try {
      const data = JSON.parse(event.data)
      const content = data.d

      if (content !== undefined && content !== null) {
        // -- 处理不同类型的数据
        //- 优先处理 思考内容
        if (thinkParser) {
          const previousThinkingContent = deepThinkingContent.value
          thinkParser.feed(content)
          // 如果思考内容有更新，保存到消息对象中
          if (deepThinkingContent.value !== previousThinkingContent) {
            const lastMessage = messages.value[messages.value.length - 1]
            lastMessage.thinkingContent = deepThinkingContent.value
          }
        }
        // 继而是 普通消息
        // 普通消息内容
        // 注意：当ThinkStreamParser存在时，只有当它处理完思考内容后，才将内容添加到fullContent
        // 这样可以确保fullContent中不会包含思考标签之前的任何片段
        if (thinkParser && thinkParser.isThinkingContentProcessed()) {
          // 过滤掉剩余的 </think> 标签片段
          const filterContent = content.replace(/<\/?think>?/g, '')
          fullContent += filterContent
        } else if (!thinkParser) {
          // 如果没有thinkParser（非深度思考模式），直接添加内容
          fullContent += content
        }
        // 更新消息显示
        const lastMessage = messages.value[messages.value.length - 1]
        lastMessage.content = getNoReasoningContent(fullContent)
        lastMessage.loading = true // 仍在接收消息时保持loading为true
        scrollToBottom()
      } else if (data.search) {
        // 搜索结果 todo
        searchResults.value.push(data.search)
        if (isWebSearch.value) {
          showSearchDrawer.value = true
        }
      }
    } catch (e) {
      console.error('解析SSE数据失败:', e)
    }
  }
  /**
   * 处理异常错误
   * @param error
   */
  eventSource.onerror = (error) => {
    if (!isSending.value) return
    try {
      if (eventSource?.readyState === EventSource.CONNECTING) {
        streamCompleted = true
        isSending.value = false
        eventSource?.close()
      } else {
        // handleError(new Error('SSE连接错误'), aiMessageIndex)
      }
    } catch (e) {
      console.error('SSE连接错误:', error)
      eventSource?.close()
      isSending.value = false
    }
  }

  eventSource.addEventListener('done', () => {
    if (streamCompleted) return
    eventSource?.close()
    isSending.value = false
    streamCompleted = true

    // 保存最终的思考内容到消息对象
    const lastMessage = messages.value[messages.value.length - 1]
    if (lastMessage && lastMessage.role === 'assistant' && deepThinkingContent.value) {
      lastMessage.thinkingContent = deepThinkingContent.value
    }

    // 清理思考消息解析器
    if (thinkParser) {
      thinkParser.reset()
      thinkParser = null
    }

    // 消息接收完成后设置loading为false
    if (lastMessage && lastMessage.role === 'assistant') {
      lastMessage.loading = false
    }

    scrollToBottom()
  })
}
/**
 * 中断生成
 */
const interruptSending = () => {
  if (eventSource) {
    eventSource.close()
    eventSource = null
  }
  isSending.value = false

  // 保存当前的思考内容到消息对象
  const lastMessage = messages.value[messages.value.length - 1]
  if (lastMessage && lastMessage.role === 'assistant' && deepThinkingContent.value) {
    lastMessage.thinkingContent = deepThinkingContent.value
  }

  // 清理思考消息解析器
  if (thinkParser) {
    thinkParser.reset()
    thinkParser = null
  }

  message.info('已中断发送')
}
/**
 * 复制消息
 * @param msg
 */
const copyMessage = (msg: Message) => {
  // 复制消息逻辑
  navigator.clipboard.writeText(msg.content)
  message.success('消息已复制到剪贴板')
}
/**
 * 重试消息
 * @param msg
 */
const retryMessage = (msg: Message) => {
  // 重试消息逻辑
  userInput.value = msg.content
  handleSend()
}
//todo 文档总结
const processDocumentLink = () => {
  // 处理文档链接逻辑
  message.success('开始处理文档链接')
  // 模拟文档处理结果
  setTimeout(() => {
    documentSummary.value = `
# 文档总结示例

## 主要内容
这是从文档链接中提取的主要内容摘要。

## 关键点
1. 第一个关键点
2. 第二个关键点
3. 第三个关键点

## 结论
文档的核心结论和建议。
    `
    showDocumentSummary.value = true
  }, 2000)
}
// todo  文件上传
const beforeUpload = (file: File) => {
  // 文件上传前检查
  const isLt100M = file.size / 1024 / 1024 < 100
  if (!isLt100M) {
    message.error('文件大小不能超过100MB!')
    return false
  }
  message.success(`${file.name} 上传成功`)

  // 模拟文档处理结果
  setTimeout(() => {
    documentSummary.value = `
# 文档总结示例

## 主要内容
这是从上传文件中提取的主要内容摘要。

## 关键点
1. 第一个关键点
2. 第二个关键点
3. 第三个关键点

## 结论
文档的核心结论和建议。
    `
    showDocumentSummary.value = true
  }, 2000)

  return false // 阻止自动上传
}

// 对话历史相关
const loadingHistory = ref(false)
const hasMoreHistory = ref(false)
const lastCreateTime = ref<string>()
const historyLoaded = ref(false)
//加载会话消息
const loadSessionMessages = async (sessionId: number, isLoadMore = false) => {
  if (!sessionId || loadingHistory.value) return
  loadingHistory.value = true
  try {
    const params: API.listAppChatHistoryParams = {
      bizId: sessionId,
      bizType: 0, // 假设1表示学习聊天类型
      pageSize: 10,
    }
    // 如果是加载更多，传递最后一条消息的创建时间作为游标
    if (isLoadMore && lastCreateTime.value) {
      params.lastCreateTime = lastCreateTime.value
    }
    // 加载会话历史消息
    const response = await api.chatHistoryController.listAppChatHistory(params)

    if (response.data?.code === 0 && response.data.data) {
      const chatHistories = response.data?.data?.records || [] // messages.value
      if (chatHistories.length > 0) {
        const historyMessages: Message[] = chatHistories
          .map((record: API.ChatHistory) => {
            const role: 'user' | 'assistant' =
              record.messageType?.toUpperCase() === 'USER' ? 'user' : 'assistant'
            return {
              id: record.id!,
              role: role,
              content: getNoReasoningContent(record.message)!,
              thinkingContent: getReasoningContent(record.message), // 添加思考内容字段
              createTime: record.createTime,
            }
          })
          .reverse() //反转数组 ，老消息在前
        if (isLoadMore) {
          // 加载更多时，将历史消息添加到开头
          messages.value.unshift(...historyMessages)
        } else {
          // 初始加载，直接设置消息列表
          messages.value = historyMessages
        }
        // 更新游标
        lastCreateTime.value = chatHistories[chatHistories.length - 1]?.createTime
        // 检查是否还有更多历史
        hasMoreHistory.value = chatHistories.length === 10
      } else {
        historyLoaded.value = true
      }
    }
  } catch (error) {
    console.error('加载对话历史失败：', error)
    message.error('加载对话历史失败')
  } finally {
    loadingHistory.value = false
  }
}
// 加载更多历史消息
const loadMoreHistory = async (sessionId: number) => {
  await loadSessionMessages(sessionId, true)
}

// 历史会话 相关
const loadingSessions = ref(false)
const hasMoreSessions = ref(false)
const lastSessionCreateTime = ref<string>()
const SessionsLoaded = ref(false)
const loadAllSessions = async (isLoadMore = false) => {
  if (loadingSessions.value) return
  loadingSessions.value = true
  try {
    const params: API.LearnChatQueryRequest = {
      pageSize: 10,
    }
    if (isLoadMore && lastSessionCreateTime.value) {
      params.lastCreateTime = lastSessionCreateTime.value
    }
    // 加载所有会话
    const response = await api.learnChatController.listMyLearnChatVoByPage(params)

    if (response.data?.code === 0 && response.data.data) {
      const chatSessions = response.data.data?.records || [] //  allSessions.value
      if (chatSessions.length > 0) {
        const allChatSessions: ChatSession[] = chatSessions.map((record: API.LearnChat) => ({
          id: record.id!,
          title: record.title!,
          createTime: record.createTime!,
          preview: record.initPrompt,
        }))
        if (isLoadMore) {
          // 加载更多时，将历史消息添加到末尾
          allSessions.value.push(...allChatSessions)
        } else {
          // 初始加载，直接设置消息列表
          allSessions.value = allChatSessions
        }
        // 更新游标
        lastSessionCreateTime.value = chatSessions[chatSessions.length - 1]?.createTime
        // 检查是否还有更多历史
        hasMoreSessions.value = chatSessions.length === 10
      } else {
        SessionsLoaded.value = true
      }
    }
  } catch (error) {
    console.error('加载会话列表失败:', error)
    message.error('加载会话列表失败')
  } finally {
    loadingSessions.value = false
  }
}
// 加载更多历史消息
const loadMoreSessions = async () => {
  await loadAllSessions(true)
}

// 处理历史会话滚动事件
const handleHistoryScroll = (event: Event) => {
  // 防抖处理，避免频繁触发
  if (loadingSessions.value) return

  // 获取历史列表容器
  const container = event.currentTarget as HTMLElement
  // 判断是否滚动到底部
  const isAtBottom = container.scrollTop + container.clientHeight >= container.scrollHeight - 10

  // 只有在滚动到底部且还有更多数据时才加载
  if (isAtBottom && hasMoreSessions.value) {
    loadMoreSessions()
  }
}
const searchSessions = async () => {
  try {
    // 搜索会话
    const response = await api.learnChatController.listMyLearnChatVoByPage({
      current: 1,
      pageSize: 20,
      title: searchKeyword.value,
    })

    if (response.data?.code === 0 && response.data.data?.records) {
      allSessions.value = response.data.data.records.map((record: API.LearnChat) => ({
        id: record.id!,
        title: record.title!,
        createTime: record.createTime!,
        preview: record.initPrompt,
      }))
    }
  } catch (error) {
    console.error('搜索会话失败:', error)
    message.error('搜索会话失败')
  }
}

const loadModels = async () => {
  try {
    // 加载可用模型
    const response = await api.learnChatController.listModel()
    if (response.data?.code === 0) {
      availableModels.value = response.data.data || []
    }
  } catch (error) {
    console.error('加载模型列表失败:', error)
    message.error('加载模型列表失败')
  }
}

//提示词相关
// 模态框控制
const showPromptModal = ref(false) //提示词
//提示词列表
const promptList = ref<API.PromptSelfVO[]>([])
//提示词科目
const selectedSubject = ref<string>('')
const promptTypeList = computed(() => {
  return [...new Set(promptList.value.map((prompt) => prompt.subject))] //使用Set去重
})

// 筛选后的提示词列表
const filteredPromptList = computed(() => {
  if (!selectedSubject.value) {
    // 如果选择的是"全部"，返回所有提示词
    return promptList.value
  }
  // 否则返回对应科目的提示词
  return promptList.value.filter((prompt) => prompt.subject === selectedSubject.value)
})

// 按时间分类的历史会话
/**
 * 今日、本周、本月、本年 的会话历史划分
 */
const categorizedSessions = computed(() => {
  const today: ChatSession[] = []
  const thisWeek: ChatSession[] = []
  const thisMonth: ChatSession[] = []
  const thisYear: ChatSession[] = []

  const now = new Date()
  const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate())
  const startOfWeek = new Date(startOfDay)
  startOfWeek.setDate(startOfWeek.getDate() - startOfWeek.getDay())
  const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1)
  const startOfYear = new Date(now.getFullYear(), 0, 1)

  allSessions.value.forEach((session) => {
    const sessionDate = new Date(session.createTime)

    if (sessionDate >= startOfDay) {
      today.push(session)
    } else if (sessionDate >= startOfWeek) {
      thisWeek.push(session)
    } else if (sessionDate >= startOfMonth) {
      thisMonth.push(session)
    } else if (sessionDate >= startOfYear) {
      thisYear.push(session)
    }
  })

  return {
    today,
    thisWeek,
    thisMonth,
    thisYear,
  }
})

// 处理科目选择变化
const handleSubjectChange = (value: string) => {
  selectedSubject.value = value
  // 这里不需要重新获取数据，只需要通过计算属性过滤现有数据
}

const openThePromptModal = async () => {
  // 如果已选中提示词，点击按钮表示取消选择
  if (selectedPrompt.value) {
    selectedPrompt.value = null
    return
  }

  //打开模态框
  await fetchPromptList()
  showPromptModal.value = true
  console.log(promptTypeList.value)
}
//提示词查询
const promptSearchParams = reactive<API.PromptSelfQueryRequest>({
  current: 1,
  pageSize: 20, //固定只能展示10个数据 TODO 瀑布流的效果，往下翻才加载
  searchText: '', // 初始化为空，获取所有提示词
})
const fetchPromptList = async () => {
  try {
    const res = await listPromptSelfVoByPage({
      ...promptSearchParams,
    })
    if (res.data.data && res.data.code === 0) {
      promptList.value = res.data.data.records ?? []
      console.log(promptList.value)
    } else {
      message.error('获取提示词失败，请稍后重试')
    }
  } catch (e) {
    message.error('获取提示词失败，请稍后重试')
  }
}

// 选择提示词
const selectPrompt = (prompt: API.PromptSelfVO) => {
  if (prompt.effect) {
    // 关闭模态框
    showPromptModal.value = false
    selectedPrompt.value = prompt
  }
}

const selectModel = (model: ModelView) => {
  selectedModel.value = model
}

const getModelAvatar = (modelName: string) => {
  const name = modelName.toLowerCase()
  if (name.includes('deepseek')) {
    return '/src/assets/ai/deep-seek.png'
  } else if (name.includes('qwen')) {
    return '/src/assets/ai/qwen.png'
  } else if (name.includes('glm')) {
    return '/src/assets/ai/zhipu.png'
  } else {
    // 默认头像，可以根据需要添加
    return '/src/assets/ai/qwen.png'
  }
}

const confirmModelSelection = () => {
  showModelSelector.value = false
  message.success(`已选择模型: ${selectedModel.value?.modelName}`)
}

const renderMarkdown = (content: string) => {
  return md.render(content || '')
}
const formatTime = (timeString: string) => {
  const date = new Date(timeString)
  return date.toLocaleString('zh-CN')
}

const scrollToBottom = () => {
  nextTick(() => {
    if (messagesContainer.value) {
      const start = messagesContainer.value.scrollTop
      const end = messagesContainer.value.scrollHeight
      const duration = 500 // 动画持续时间（毫秒）
      const startTime = performance.now()

      const animateScroll = (currentTime: number) => {
        const elapsedTime = currentTime - startTime
        const progress = Math.min(elapsedTime / duration, 1)

        // 使用缓动函数使滚动更自然
        const easeInOutQuad = (t: number) => {
          return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t
        }

        const scrollPosition = start + (end - start) * easeInOutQuad(progress)
        messagesContainer.value.scrollTop = scrollPosition

        if (progress < 1) {
          requestAnimationFrame(animateScroll)
        }
      }

      requestAnimationFrame(animateScroll)
    }
  })
}

const showAttachmentInfo = () => {
  message.info('支持上传文件（最多50个，每个100MB）接受pdf、doc、xlsx、ppt、txt、图片等')
}

// 快捷键处理
const handleKeyDown = (e: KeyboardEvent) => {
  // Ctrl+K 快捷键创建新会话
  if (e.ctrlKey && e.key === 'k') {
    e.preventDefault()
    createNewSession()
  }
}

// 生命周期钩子
onMounted(() => {
  // 初始化数据
  loadModels()
  // 加载最近会话
  loadAllSessions().then(() => {
    // 取前5个作为最近会话
    recentSessions.value = allSessions.value.slice(0, 5)
  })

  // 注册快捷键
  window.addEventListener('keydown', handleKeyDown)

  // 启动快捷提问定时切换
  startQuickQuestionTimer()
})

onUnmounted(() => {
  // 清理EventSource
  if (eventSource) {
    eventSource.close()
    eventSource = null
  }

  // 移除快捷键监听
  window.removeEventListener('keydown', handleKeyDown)

  // 停止快捷提问定时切换
  stopQuickQuestionTimer()
})
</script>

<style scoped>
/* Import Kaushan Script font */
@font-face {
  font-family: 'Kaushan Script';
  src: url('@/assets/font/KaushanScript-Regular.otf') format('opentype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

/* 统一设置font-awesome图标颜色 */
.fa {
  color: #20a1da;
}

/* 增强提示词按钮样式 */
.enhance-btn {
  position: relative;
  transition: all 0.3s ease;
}

.enhance-btn.active {
  color: #20a1da;
  background-color: rgba(32, 161, 218, 0.1);
}

.enhance-btn:hover {
  color: #20a1da;
  background-color: rgba(32, 161, 218, 0.1);
}

/* 增强提示词动画效果 */
@keyframes enhanceAnimation {
  0% {
    opacity: 0.5;
  }
  50% {
    opacity: 1;
    transform: scale(1.05);
  }
  100% {
    opacity: 1;
  }
}

@keyframes curtainShine {
  0% {
    transform: scale(1);
    filter: brightness(1);
    text-shadow: none;
  }
  10% {
    transform: scale(1.01);
    filter: brightness(1.2);
    text-shadow: 0 0 5px rgba(255, 215, 0, 0.5);
  }
  30% {
    transform: scale(1.02);
    filter: brightness(1.5);
    text-shadow: 0 0 15px rgba(255, 215, 0, 0.8);
  }
  50% {
    transform: scale(1.03);
    filter: brightness(2);
    text-shadow:
      0 0 25px rgba(255, 215, 0, 1),
      0 0 35px rgba(255, 215, 0, 0.8);
  }
  70% {
    transform: scale(1.02);
    filter: brightness(1.5);
    text-shadow: 0 0 15px rgba(255, 215, 0, 0.8);
  }
  90% {
    transform: scale(1.01);
    filter: brightness(1.2);
    text-shadow: 0 0 5px rgba(255, 215, 0, 0.5);
  }
  100% {
    transform: scale(1);
    filter: brightness(1);
    text-shadow: none;
  }
}

.enhance-btn.animating {
  animation: curtainShine 1.5s ease-in-out;
}

/* 输入框光芒效果 */
.input-with-shine {
  position: relative;
  overflow: hidden;
}

.input-with-shine::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 50%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(255, 215, 0, 0.8), transparent);
  animation: shineAcross 1.5s ease-in-out;
}

.input-with-shine::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: radial-gradient(circle at center, rgba(255, 215, 0, 0.4) 0%, transparent 70%);
  opacity: 0;
  animation: curtainShinePulse 1.5s ease-in-out;
}

@keyframes shineAcross {
  0% {
    left: -100%;
  }
  100% {
    left: 100%;
  }
}

@keyframes curtainShinePulse {
  0% {
    opacity: 0;
    transform: scale(0.8);
  }
  50% {
    opacity: 1;
    transform: scale(1.1);
  }
  100% {
    opacity: 0;
    transform: scale(1.2);
  }
}
.chat-container {
  display: flex;
  height: v-bind('isFullscreen ? "100vh" : "93vh"');
  background-color: #f5f5f5;
}

.sidebar {
  width: 200px;
  background: #fff;
  border-right: 1px solid #e8e8e8;
  display: flex;
  flex-direction: column;
  transition: all 0.3s;
  box-shadow: 2px 0 8px rgba(0, 0, 0, 0.05);
}

.sidebar.collapsed {
  width: 60px;
}

.sidebar-header {
  padding: 10px;
  border-bottom: 1px solid #e8e8e8;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.sidebar-header h2 {
  margin: 0;
  margin-left: 25px;
  font-size: 18px;
  color: #20a1da;
  font-family: 'Kaushan Script', cursive;
}

.sidebar-content {
  flex: 1;
  padding: 16px;
  overflow-y: auto;
}

.new-session-btn {
  margin-bottom: 16px;
  background-color: #20a1da;
  border-color: #20a1da;
}

.mode-selector {
  margin-bottom: 24px;
}

.history-section h3 {
  margin: 0 0 12px 0;
  font-size: 14px;
  color: #666;
}

.history-section h3 i {
  color: #20a1da;
}

.session-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  border-radius: 4px;
  cursor: pointer;
  margin-bottom: 8px;
  transition: all 0.3s;
}

.session-item:hover,
.session-item.active {
  background-color: #e6f7ff;
}

.session-info {
  flex: 1;
  overflow: hidden;
}

.session-title {
  display: block;
  font-size: 14px;
  color: #333;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.session-time {
  font-size: 12px;
  color: #999;
}

.session-time i {
  color: #20a1da;
}

.view-all-btn {
  margin-top: 8px;
  color: #20a1da;
}

.view-all-btn i {
  color: #20a1da;
}

.sidebar-footer {
  padding: 16px;
  border-top: 1px solid #e8e8e8;
}

.main-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.initial-state {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px;
}

.welcome-section {
  text-align: center;
  max-width: 800px;
  width: 100%;
}

.welcome-section h1 {
  font-size: 48px;
  margin-bottom: 32px;
  color: #20a1da;
  font-weight: 600;
  font-family: 'Kaushan Script', cursive;
}

.input-container-wrapper {
  background: #fff;
  position: relative;
  margin-bottom: 12px;
  display: flex;
  justify-content: center;
  width: 100%;
}

.input-container {
  position: relative;
  background: #fff;
  border: 1px solid #d9d9d9;
  border-radius: 8px;
  padding: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  transition: all 0.3s;
  width: 100%;
  max-width: 800px;
}

.input-container:hover {
  border-color: #20a1da;
  box-shadow: 0 2px 8px rgba(32, 161, 218, 0.2);
}

.main-input {
  border: none !important;
  box-shadow: none !important;
  resize: none;
}

.main-input:focus {
  box-shadow: none !important;
}

.input-actions {
  display: flex;
  align-items: center;
  margin-top: 12px;
  position: relative;
}

.action-btn {
  font-size: 12px;
  padding: 4px 8px;
  color: #666;
  transition: all 0.3s;
}

.action-btn:hover {
  color: #20a1da;
}

.action-btn.active {
  color: #20a1da;
  font-weight: bold;
}

.deep-thinking-btn {
  position: absolute;
  left: 0;
  bottom: 0;
}

.web-search-btn {
  position: absolute;
  left: 80px;
  bottom: 0;
}

.attachment-btn {
  position: absolute;
  right: 110px;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 4px;
}

.enhance-btn {
  position: absolute;
  right: 80px;
  bottom: 0;
}

.send-btn {
  position: absolute;
  right: 0;
  bottom: 0;
  padding: 4px 16px;
}

.send-btn:disabled {
  background-color: #f5f5f5;
  border-color: #d9d9d9;
  color: rgba(0, 0, 0, 0.25);
}

.quick-questions {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.quick-questions h3 {
  color: #20a1da;
}

.quick-questions h3 i {
  color: #20a1da;
}

.question-row {
  display: flex;
  justify-content: center;
  gap: 16px;
}

/* 思考折叠框样式 */
.deep-thinking-section {
  margin-bottom: 16px;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid #e8e8e8;
}

.deep-thinking-section .ant-collapse {
  border: none;
  background: transparent;
}

.deep-thinking-section .ant-collapse-header {
  background: #f8f9fa;
  padding: 12px 16px;
  font-weight: 500;
  color: #333;
  border-bottom: 1px solid #e8e8e8;
}

.deep-thinking-section .ant-collapse-content {
  background: #fff;
  border-top: none;
}

.deep-thinking-section .ant-collapse-content-box {
  padding: 16px;
}

.thinking-content {
  color: #666;
  font-size: 14px;
  line-height: 1.6;
}

.thinking-content h1,
.thinking-content h2,
.thinking-content h3,
.thinking-content h4,
.thinking-content h5,
.thinking-content h6 {
  color: #333;
  margin-top: 16px;
  margin-bottom: 8px;
}

.thinking-content p {
  margin-bottom: 12px;
  font-size: 12px;
}

.thinking-content code {
  background: #f5f5f5;
  padding: 2px 4px;
  border-radius: 3px;
  font-family: 'Courier New', monospace;
}

.thinking-content pre {
  background: #f5f5f5;
  padding: 12px;
  border-radius: 4px;
  overflow-x: auto;
  margin-bottom: 12px;
}

.question-row a-button {
  flex: 1;
  max-width: 200px;
}

.question-row a-button i {
  color: #20a1da;
  margin-right: 4px;
}

.chat-state {
  display: flex;
  flex-direction: column;
  background: #fff;
  height: 100%;
}

.chat-header {
  margin-top: 15px;
  padding: 16px;
  background: #fff;
  display: flex;
  align-items: center;
  gap: 10px;
  justify-content: center;
}

.chat-header a-button {
  display: flex;
  align-items: center;
  gap: 4px;
}

/* 提示词模态框样式 */
.prompt-categories {
  max-height: 500px;
  overflow-y: auto;
}

/* 科目标签页样式 */
.subject-tabs {
  margin-bottom: 20px;
}

/* 提示词卡片容器 */
.prompt-cards-container {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  padding: 0 10px;
}

/* 提示词卡片样式 */
.prompt-card {
  width: 220px;
  padding: 20px;
  border: 1px solid rgba(22, 119, 255, 0.2);
  border-radius: 16px;
  cursor: pointer;
  transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1);
  position: relative;
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(5px);
  overflow: hidden;
  animation: fadeInCard 0.6s ease-out;
  animation-delay: calc(var(--card-index, 0) * 0.1s);
}

.prompt-card:nth-child(1) {
  --card-index: 0;
}
.prompt-card:nth-child(2) {
  --card-index: 1;
}
.prompt-card:nth-child(3) {
  --card-index: 2;
}
.prompt-card:nth-child(4) {
  --card-index: 3;
}
.prompt-card:nth-child(5) {
  --card-index: 4;
}

.prompt-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(90deg, transparent, rgba(22, 119, 255, 0.1), transparent);
  transition: left 0.6s ease;
}

.prompt-card:hover::before {
  left: 100%;
}

.prompt-card:hover {
  border-color: #1677ff;
  box-shadow: 0 8px 25px rgba(22, 119, 255, 0.2);
  transform: translateY(-5px) scale(1.02);
}

.prompt-card.active {
  border: 2px solid #1677ff;
  box-shadow: 0 8px 25px rgba(22, 119, 255, 0.3);
  transform: translateY(-5px) scale(1.02);
  background: linear-gradient(135deg, rgba(22, 119, 255, 0.05), rgba(64, 150, 255, 0.05));
}

@keyframes fadeInCard {
  from {
    opacity: 0;
    transform: translateY(20px) scale(0.9);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.card-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.card-avatar {
  background: linear-gradient(135deg, #1677ff, #4096ff);
  font-size: 16px;
  font-weight: bold;
  box-shadow: 0 4px 12px rgba(22, 119, 255, 0.3);
  transition: all 0.3s ease;
}

.prompt-card:hover .card-avatar {
  transform: scale(1.1) rotate(5deg);
}

.card-title {
  font-size: 16px;
}

.card-desc {
  font-size: 13px;
  color: #666;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}
.messages-container {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  background: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
}
/* 加载更多按钮 */
.load-more-container {
  text-align: center;
  padding: 8px 0;
  margin-bottom: 16px;
}
.messages-wrapper {
  width: 100%;
  max-width: 800px;
}

.message {
  display: flex;
  margin-bottom: 24px;
  width: 100%;
  align-items: flex-start;
}

.message.user {
  flex-direction: row-reverse;
}

.message.assistant {
  flex-direction: row;
}

.message-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: #20a1da;
  color: white;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-shrink: 0;
}

.message-avatar img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
}

.message-content {
  padding: 12px 16px;
  border-radius: 8px;
  position: relative;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
  display: inline-block;
  max-width: 80%;
  word-wrap: break-word;
  width: fit-content;
}

.message-header {
  margin-bottom: 8px;
  font-weight: bold;
  color: #20a1da;
  display: flex;
  align-items: center;
  gap: 4px;
}

.message-header i {
  color: #20a1da;
}

.assistant-label {
  display: flex;
  align-items: center;
  gap: 4px;
}

.message.user .message-content {
  background: #20a1da;
  color: white;
  margin-left: auto;
  margin-right: 12px;
  min-width: 100px;
}

.message.assistant .message-content {
  background: #f0f0f0;
  color: #333;
  margin-right: auto;
  margin-left: 12px;
}

.message-text {
  line-height: 1.5;
}

.loading-indicator {
  margin-top: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.loading-text {
  font-size: 12px;
  color: #999;
}

.message-actions {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}

.deep-thinking-section {
  margin: 20px 0;
  padding: 16px;
  background: #f9f9f9;
  border-radius: 8px;
  /*  border-left: 4px solid #20a1da;*/
  width: 100%;
  max-width: 800px;
}

.deep-thinking-section :deep(.ant-collapse-header) {
  font-weight: bold;
  color: #20a1da;
}

.document-state {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px;
}

.document-container {
  max-width: 600px;
  width: 100%;
  text-align: center;
}

.document-container h2 {
  color: #20a1da;
}

.document-container h2 i {
  color: #20a1da;
}

.upload-section {
  margin-top: 32px;
}

.upload-section i {
  color: #20a1da;
}

.link-input {
  margin-top: 24px;
  text-align: left;
}

.link-input a-button {
  background-color: #20a1da;
  border-color: #20a1da;
}

.link-input a-button i {
  color: white;
}

.history-state {
  padding: 20px;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  align-items: center;
}

.history-header {
  margin-bottom: 20px;
  width: 100%;
  max-width: 800px;
  text-align: center;
}

.history-header h2 {
  color: #20a1da;
}

.history-header h2 i {
  color: #20a1da;
}

.history-list {
  width: 100%;
  max-width: 800px;
  /*overflow-y: auto;*/ /* 已调整为 由父 <history-state>决定*/
  max-height: calc(100vh - 200px);
  padding-right: 10px;
}

.time-section {
  margin-bottom: 30px;
}

.time-title {
  font-size: 18px;
  font-weight: bold;
  color: #20a1da;
  margin-bottom: 15px;
  padding-bottom: 5px;
  border-bottom: 2px solid #20a1da;
}

.history-item {
  padding: 16px;
  border: 1px solid #e8e8e8;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s;
  margin-bottom: 10px;
}

.history-item:hover {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

.history-info h3 {
  margin: 0 0 8px 0;
  font-size: 16px;
  color: #20a1da;
}

.history-info h3 i {
  color: #20a1da;
}

.history-info p {
  margin: 0 0 8px 0;
  color: #666;
  font-size: 14px;
}

.history-time {
  font-size: 12px;
  color: #999;
}

.history-time i {
  color: #20a1da;
}

.load-more-trigger {
  margin-top: 20px;
  text-align: center;
  padding: 15px;
  border-radius: 8px;
  background-color: #f5f5f5;
  cursor: pointer;
  transition: all 0.3s;
}

.load-more-trigger:hover {
  background-color: #e6f7ff;
}

.load-more-text {
  color: #20a1da;
  font-weight: bold;
}

.load-more-text i {
  margin-right: 5px;
}

.search-results {
  height: 100%;
  overflow-y: auto;
  padding: 0 16px;
}

.search-results h3 {
  margin-top: 0;
  color: #20a1da;
  display: flex;
  align-items: center;
  gap: 8px;
}

.search-results h3 i {
  color: #20a1da;
}

.search-result-item {
  margin-bottom: 24px;
  padding-bottom: 16px;
  border-bottom: 1px solid #e8e8e8;
}

.search-result-item h4 {
  margin: 0 0 8px 0;
  color: #20a1da;
  display: flex;
  align-items: center;
  gap: 6px;
}

.search-result-item h4 i {
  color: #20a1da;
}

.search-result-item p {
  margin: 0 0 8px 0;
  color: #333;
  font-size: 14px;
}

.search-result-item a {
  font-size: 12px;
  color: #999;
}

.summary-content {
  padding: 16px;
  background: #f9f9f9;
  border-radius: 8px;
}

:deep(.ant-list-item.selected) {
  background-color: #e6f7ff;
}

.loading-indicator {
  margin-top: 8px;
}

.deep-thinking-section {
  margin: 20px auto;
  padding: 16px;
  background: #f9f9f9;
  border-radius: 8px;
  /*  border-left: 4px solid #20a1da;*/
  width: 100%;
  max-width: 800px;
}

.deep-thinking-section :deep(.ant-collapse-header) {
  font-weight: bold;
  color: #20a1da;
}

/* 统一设置font-awesome图标颜色 */
.fa {
  color: #20a1da;
}

/* 模型卡片样式 */
.model-cards-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
  margin-top: 16px;
}

.model-card {
  border: 1px solid #e8e8e8;
  border-radius: 12px;
  padding: 16px;
  cursor: pointer;
  transition: all 0.3s ease;
  background: #fff;
  text-align: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.model-card:hover {
  border-color: #20a1da;
  box-shadow: 0 4px 16px rgba(32, 161, 218, 0.2);
  transform: translateY(-2px);
}

.model-card.selected {
  border-color: #20a1da;
  background-color: #e6f7ff;
  box-shadow: 0 4px 16px rgba(32, 161, 218, 0.3);
}

.model-avatar {
  margin-bottom: 12px;
}

.model-avatar img {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid #f0f0f0;
  transition: all 0.3s ease;
}

.model-card:hover .model-avatar img {
  border-color: #20a1da;
  transform: scale(1.1);
}

.model-info {
  text-align: center;
}

.model-name {
  font-size: 16px;
  font-weight: 600;
  color: #333;
  margin-bottom: 8px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.model-description {
  font-size: 12px;
  color: #666;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  min-height: 32px;
}

/* 滑动到底部按钮样式 */
.toBottom {
  position: absolute;
  left: 55%;
  bottom: v-bind('isFullscreen ? "20%" : "14%"');

  transform: translateX(-50%);
  z-index: 10;
  transition: all 0.3s ease;
}

.toBottom .scroll-button {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #20a1da;
  border: none;
  color: white;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  transition: all 0.3s ease;
  position: relative;
  z-index: 2;
}

.toBottom .scroll-button:hover {
  /* background-color: #1890ff; */
  transform: scale(1.1);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.toBottom.sending {
  animation: pulse 2s infinite;
}

.arc-animation {
  position: absolute;
  top: -10px;
  left: -10px;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  border: 2px solid transparent;
  border-top-color: #20a1da;
  border-right-color: rgba(32, 161, 218, 0.7);
  animation: arc-spin 1.5s linear infinite;
  z-index: 1;
}

.arc-animation::before {
  content: '';
  position: absolute;
  top: -2px;
  left: -2px;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  border: 2px solid transparent;
  border-top-color: rgba(32, 161, 218, 0.5);
  border-right-color: rgba(32, 161, 218, 0.3);
  animation: arc-spin 2s linear infinite reverse;
}

.arc-animation::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 1px solid transparent;
  border-bottom-color: rgba(32, 161, 218, 0.3);
  border-left-color: rgba(32, 161, 218, 0.1);
  animation: arc-spin 1s linear infinite;
}

@keyframes arc-spin {
  0% {
    transform: rotate(0deg);
    opacity: 1;
  }
  50% {
    opacity: 0.7;
  }
  100% {
    transform: rotate(360deg);
    opacity: 1;
  }
}

@keyframes pulse {
  0% {
    transform: translateX(-50%) scale(1);
  }
  50% {
    transform: translateX(-50%) scale(1.05);
  }
  100% {
    transform: translateX(-50%) scale(1);
  }
}
</style>
